using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace PhpDocBlockGenerator.Model.Php
{
    /// <summary>
    /// collection of misc methods which are used in some classes
    /// </summary>
    public abstract class StaticMethods
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="exceptedLines"></param>
        /// <param name="beginningLine"></param>
        /// <returns></returns>
        public static List<int> AdaptExceptedLines(List<int> exceptedLines, int beginningLine)
        {
            return exceptedLines.Select(t => t - beginningLine).ToList();
        }

        /// <summary>
        /// searches for a docblock above from the given position
        /// </summary>
        /// <param name="fileArr">whole php file as list of lines</param>
        /// <param name="beginningLine">specifies the position to search from in the whole file (position in list of file lines)</param>
        /// <param name="outDocBlockBegin">returns the beginning position of the doc block</param>
        /// <param name="outDocBlockEnd">returns the ending position of the doc block</param>
        public static void ParseDocBlockPos(List<String> fileArr, int beginningLine, out int outDocBlockBegin, out int outDocBlockEnd)
        {
            //active-docblock-flag 
            bool activeDocBlock = false;
            outDocBlockBegin = -1;
            outDocBlockEnd = -1;

            //loop backwards from given position over the array
            for (int i = beginningLine - 1; i >= 0; --i)
            {
                //if end of docblock wasnt already found
                if (!activeDocBlock)
                {
                    //search for end of docblock/multiline-comment ( */ )
                    MatchCollection regEndOfDocBlockResult = PhpRegex.RegSearchEndOfDocBlock.Matches(fileArr[i]);

                    //if sth was found, set the active-docblock-flag and the endline for
                    //the docblock
                    if (regEndOfDocBlockResult.Count > 0)
                    {
                        outDocBlockEnd = i;
                        activeDocBlock = true;
                    }
                    else
                    {
                        // search for other things, which aren't part of the doc block "{", "}", ";"
                        String temp = fileArr[i].Trim();
                        MatchCollection regEndOfPreviousLogicResult = PhpRegex.RegSearchEndOfPreviousLogic.Matches(temp);

                        // if sth was found -> break
                        if (regEndOfPreviousLogicResult.Count > 0)
                            break;
                    }
                }
                // end of docblock was already found
                else
                {
                    //search for the beginning of a docblock ( /** )
                    MatchCollection regBeginOfDocBlockResult = PhpRegex.RegSearchBeginOfDocBlock.Matches(fileArr[i]);

                    //if sth was found, set beginningline and break
                    if (regBeginOfDocBlockResult.Count > 0)
                    {
                        outDocBlockBegin = i;
                        break;
                    }

                    //search for the beginning of a multiline comment ( /* )                    
                    MatchCollection regBeginningOfCommentResult = PhpRegex.RegSearchBeginOfComment.Matches(fileArr[i]);
                    
                    //if sth was found, set teh active-docblock-flag and break
                    if (regBeginningOfCommentResult.Count > 0)
                    {
                        activeDocBlock = false;
                        break;
                    }

                    //if the actual line is the beginning of the file, set active-docblock-flag
                    if (0 == i)
                        activeDocBlock = false;
                }
            }

            // if no docblock was found
            if (!activeDocBlock)
            {
                outDocBlockBegin = -1;
                outDocBlockEnd = -1;
            }
        }
    }
}
